package com.example.templatedemo.observable

import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import kotlin.reflect.KProperty1

class FieldLiveData<T : DataCallback>(
    initialValue: T?=null,
) : MutableLiveData<T>() {
    private var lastValue: T? = null

    // 用于保存字段观察者，支持生命周期自动移除
    private val fieldObservers =
        mutableMapOf<String, MutableList<LifecycleBoundFieldObserver<T, *>>>()

    private data class LifecycleBoundFieldObserver<T : Any, R>(
        val owner: LifecycleOwner?,
        val field: KProperty1<T, R>,
        val compare: (old: R?, new: R?) -> Boolean,
        val observer: (R?) -> Unit,
        var needObserver: Boolean = false,
    )

    /** ✅ 观察对象的某个字段（支持生命周期） */
    fun <R> observeField(
        owner: LifecycleOwner,
        field: KProperty1<T, R>,
        observer: (R?) -> Unit,
        compare: (old: R?, new: R?) -> Boolean = { a, b -> a?.equals(b) == true },
    ) {
        val fieldName = field.name
        val list = fieldObservers.getOrPut(fieldName) { mutableListOf() }

        val wrapper = LifecycleBoundFieldObserver(owner, field, compare, observer)
        list.add(wrapper)

        // 🔒 生命周期结束时移除观察者
        owner.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onDestroy(owner: LifecycleOwner) {
                fieldObservers[fieldName]?.removeAll { it.owner == owner }
            }

            override fun onStart(owner: LifecycleOwner) {
                val currentValue = value ?: return
                val newFieldValue = wrapper.field.get(currentValue)
                if (wrapper.needObserver) {
                    wrapper.observer(newFieldValue)
                }
            }
        })

        // 🔥 注册后立即触发一次当前值
        value?.let { observer(field.get(it)) }
    }

    fun <R> observeFieldForever(
        field: KProperty1<T, R>,
        observer: (R?) -> Unit,
        compare: (old: R?, new: R?) -> Boolean = { a, b -> a?.equals(b) == true },
    ) {
        val fieldName = field.name
        val list = fieldObservers.getOrPut(fieldName) { mutableListOf() }

        val wrapper = LifecycleBoundFieldObserver(null, field, compare, observer)
        list.add(wrapper)

        // 🔥 注册后立即触发一次当前值
        value?.let { observer(field.get(it)) }
    }

    fun <R> removeFieldObserver(field: KProperty1<T, R>, observer: (R?) -> Unit) {
        val fieldName = field.name
        fieldObservers[fieldName]?.removeAll { it.observer == observer }
    }

    /** 更新值并手动触发属性变化 */
    override fun setValue(value: T?) {
        val oldValue = lastValue
        if (value != null) {
            lastValue = value.deepCopy() as T
        } else {
            lastValue = null
        }

        if (oldValue != null || value != null) {
            // 正常对比两个对象的字段差异
            notifyFieldChanges(oldValue, value)
        }

        // 内容整体变化才触发 LiveData 自身更新
        if ((oldValue == null && value != null) || (oldValue != null && value == null)) {
            super.setValue(value)
        }
        if (oldValue != null && value != null && !oldValue.isContentSame(value as DataCallback)) {
            super.setValue(value)
        }
    }

    /** 🔍 通知属性变化 */
    private fun <T : DataCallback> notifyFieldChanges(oldValue: T?, newValue: T?) {
        if (oldValue == null && newValue == null) return
        fieldObservers.forEach { (_, list) ->
            val iterator = list.iterator()
            while (iterator.hasNext()) {
                val fo = iterator.next()
                if (fo.owner != null) {
                    if (!fo.owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
                        fo.needObserver = true
                        continue
                    } else {
                        fo.needObserver = false
                    }
                }
                fo as LifecycleBoundFieldObserver<T, Any?>
                // 内容整体变化才触发 LiveData 自身更新
                if (oldValue == null ||newValue==null) {
                    if(oldValue==null) {
                        fo.observer(fo.field.get(newValue!!))
                    }else{
                        fo.observer(null)
                    }
                }else {
                    val oldFieldValue = fo.field.get(oldValue)
                    val newFieldValue = fo.field.get(newValue)
                    val changed = !fo.compare(oldFieldValue, newFieldValue)
                    if (changed) {
                        fo.observer(newFieldValue)
                    }
                }
            }
        }
    }
}


